package com.kunlun.basedata.limit.service.impl;

import com.kunlun.basedata.limit.dao.ICorrelateDao;
import com.kunlun.basedata.limit.model.CorrelateModel;
import com.kunlun.basedata.limit.model.po.CorrelatePo;
import com.kunlun.basedata.limit.model.vo.CorrelateVo;
import com.kunlun.basedata.limit.model.vo.UserRelateVo;
import com.kunlun.basedata.limit.service.ICorrelateService;
import com.kunlun.basedata.organize.model.vo.ApplicationVo;
import com.kunlun.basedata.organize.model.vo.CompanyVo;
import com.kunlun.basedata.organize.service.ICompanyService;
import com.kunlun.basedata.user.model.UserModel;
import com.kunlun.basedata.user.service.IUserService;
import com.kunlun.basedata.utils.CommonUtil;
import com.kunlun.common.model.Page;
import com.kunlun.common.utils.TreeUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 岗位业务Service类
 */
@Service
@Transactional
public class CorrelateService implements ICorrelateService {

    private final Logger logger = LogManager.getLogger();

    @Autowired
    private ICorrelateDao correlateDao;

    @Autowired
    private IUserService userService;

    @Override
    public List<CorrelateVo> getUnitNodeTree(String type) throws Exception {
        Map<String, Object> queryMap = new HashMap<>();
        List<CorrelateVo> companyVos = correlateDao.getUnitNodeTree(queryMap);
        if ("2".equals(type)) {
            companyVos = companyVos.stream().filter(obj -> "5".equals(obj.getDataType()) && StringUtils.isEmpty(obj.getParentId())).collect(Collectors.toList());
        } else if ("3".equals(type)) {
            companyVos = companyVos.stream().filter(obj -> "5".equals(obj.getDataType())).collect(Collectors.toList());
        } else if ("4".equals(type)) {
            companyVos = companyVos.stream().filter(obj -> "3,5".contains(obj.getDataType())).collect(Collectors.toList());
        } else if ("5".equals(type)) {
            companyVos = companyVos.stream().filter(obj -> "3,4,5".contains(obj.getDataType())).collect(Collectors.toList());
        }
        List<CorrelateVo> companyTrees = TreeUtil.buildTree(companyVos);
        return companyTrees;
    }

    @Override
    public List<CorrelateVo> getCorrelateList(Map<String, Object> queryMap) throws Exception {
        List<CorrelateVo> companyVos = correlateDao.getCorrelateList(queryMap);
        return companyVos;
    }

    @Override
    public Page<CorrelateVo> getCorrelatePage(CorrelatePo correlatePo, int currentPage, int pageSize) throws Exception {
        int startIndex = (currentPage - 1) * pageSize;
        Map<String, Object> queryMap = CommonUtil.packageQueryMap(correlatePo, startIndex, pageSize);
        int count = correlateDao.getCorrelateCount(queryMap);

        List<CorrelateVo> correlateVos = null;
        if (!ObjectUtils.isEmpty(correlatePo.getType()) && "0".equals(correlatePo.getType())) {
            correlateVos = correlateDao.getCorrelateRolePage(queryMap);
        } else if (!ObjectUtils.isEmpty(correlatePo.getType()) && "1".equals(correlatePo.getType())) {
            correlateVos = correlateDao.getCorrelateUserPage(queryMap);
        } else if (!ObjectUtils.isEmpty(correlatePo.getType()) && "2".equals(correlatePo.getType())) {
            correlateVos = correlateDao.getCorrelateApplicationPage(queryMap);
        } else if (!ObjectUtils.isEmpty(correlatePo.getType()) && "3".equals(correlatePo.getType())) {
            correlateVos = correlateDao.getCorrelateDepartmentPage(queryMap);
        } else if (!ObjectUtils.isEmpty(correlatePo.getType()) && "4".equals(correlatePo.getType())) {
            correlateVos = correlateDao.getCorrelatePostPage(queryMap);
        }

        Page<CorrelateVo> page = new Page<>();
        page.setCurrentPage(currentPage);
        page.setPageSize(pageSize);
        page.setTotal(count);
        page.setRecords(correlateVos);
        return page;
    }

    @Override
    public void addCorrelate(CorrelateModel correlateModel) throws Exception {
        correlateDao.addCorrelate(correlateModel);
    }

    @Override
    public void addCorrelate(CorrelatePo correlatePo) throws Exception {
        boolean isRelatedUser = "0".contains(correlatePo.getType());
        List<String> subjectIds = Arrays.asList(correlatePo.getSubjectId().split(","));
        for (String subjectId : subjectIds) {
            String targetCode = correlatePo.getTargetCode();
            CorrelateModel correlateModel = new CorrelateModel();
            correlateModel.setId(CommonUtil.generateUUID());
            correlateModel.setTargetId(correlatePo.getTargetId());
            correlateModel.setType(Integer.valueOf(correlatePo.getType()));
            correlateModel.setSubjectId("5".equals(correlatePo.getType()) ? null : subjectId);
            if (isRelatedUser) {
                correlateModel.setTargetKey(correlatePo.getTargetCode());
            } else {
                int index = targetCode.lastIndexOf("_");
                correlateModel.setTargetKey(targetCode.substring(index + 1));
                correlateModel.setVirtualId(CommonUtil.generateUUID());
                correlateModel.setVirtualParent(targetCode.substring(index + 1));
                correlateModel.setVirtualCode("5".equals(correlatePo.getType()) ? correlateModel.getVirtualId() : (targetCode + "_" + correlateModel.getVirtualId()));
            }
            correlateDao.addCorrelate(correlateModel);
        }
    }

    @Override
    public UserRelateVo getCorrelateTeanatAndAppByUser(String tenantId, String appId, String userId) throws Exception {
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("userId", userId);

        UserModel userModel = userService.getUserById(userId);

        List<CompanyVo> tenantList = new ArrayList<>();
        List<ApplicationVo> appList = new ArrayList<>();
        Set<String> tenantIdSet = new HashSet<>();
        List<CorrelateVo> correlateTeanatAndApps = correlateDao.getCorrelateTeanatAndAppByUser(queryMap);
        for (CorrelateVo tenantAppVo : correlateTeanatAndApps) {
            if (tenantIdSet.add(tenantAppVo.getTargetId())) {
                CompanyVo companyVo = new CompanyVo(tenantAppVo);
                tenantList.add(companyVo);
            }

            ApplicationVo applicationVo = new ApplicationVo(tenantAppVo);
            appList.add(applicationVo);
        }

        CorrelateVo tenantAppVo = correlateTeanatAndApps.get(0);
        UserRelateVo userRelateVo = new UserRelateVo();
        userRelateVo.setUserId(userId);
        userRelateVo.setUserName(userModel.getUserName());
        userRelateVo.setTenantId(tenantAppVo.getTargetId());
        userRelateVo.setTenantName(tenantAppVo.getTargetName());
        userRelateVo.setAppId(tenantAppVo.getSubjectId());
        userRelateVo.setAppName(tenantAppVo.getSubjectName());
        userRelateVo.setTenantList(tenantList);
        userRelateVo.setAppList(appList);
        return userRelateVo;
    }

    @Override
    public UserRelateVo getCorrelateByUser(String tenantId, String appId, String userId) throws Exception {
        UserModel userModel = userService.getUserById(userId);

        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("userId", userId);

        List<CorrelateVo> roleList = correlateDao.getRelateRoleList(queryMap);

        List<CorrelateVo> organizeList = correlateDao.getCorrelateByUser(queryMap);

        List<CorrelateVo> correlateTeanatAndAppVos = correlateDao.getCorrelateTeanatAndAppByUser(queryMap);
        CorrelateVo correlateTeanatAndAppVo = correlateTeanatAndAppVos.stream().filter(obj -> tenantId.equals(obj.getTargetId()) && appId.equals(obj.getSubjectId())).findFirst().orElse(new CorrelateVo());

        organizeList = TreeUtil.buildTree(organizeList);
        organizeList = organizeList.stream().filter(obj -> tenantId.equals(obj.getId())).collect(Collectors.toList());

        UserRelateVo userRelateVo = new UserRelateVo();
        userRelateVo.setUserId(userId);
        userRelateVo.setUserName(userModel.getUserName());
        userRelateVo.setTenantId(tenantId);
        userRelateVo.setTenantName(correlateTeanatAndAppVo.getTargetName());
        userRelateVo.setAppId(appId);
        userRelateVo.setAppName(correlateTeanatAndAppVo.getSubjectName());
        userRelateVo.setOrganizeList(organizeList);
        userRelateVo.setRoleList(roleList);
        return userRelateVo;
    }
}
